package gormv2

/**
 * @Author: prince.lee <leeprince@foxmail.com>
 * @Date:   2024-07-26 16:04:51
 * @Desc:   DAO 的基本方法
 */

import (
	"database/sql"
	"gitee.com/youbeiwuhuan/go-xxljob/tools/reflects"
	"gorm.io/gorm"
	"reflect"
)

const (
	// 分页器时，默认允许最大的记录数
	MaxLimit = 1000
)

// 初始化 gorm 实例的其他字段
type BaseDao[T any] struct {
	db        *gorm.DB
	model     T
	modelType reflect.Type
}

func NewBaseDao[T any](db0 *gorm.DB, model0 T) *BaseDao[T] {
	if reflects.IsStruct(model0) {
		panic("model0 is not a struct !")
	}

	return &BaseDao[T]{
		db:        db0,
		model:     model0,
		modelType: reflect.TypeOf(&model0),
	}
}

func (dao *BaseDao[T]) insert(entityData T) int64 {
	tx := dao.db.Save(&entityData)
	return tx.RowsAffected
}

func (dao *BaseDao[T]) GetById(id int64) T {
	u := dao.model
	// 根据主键获取记录（仅适用于整型主键）
	dao.db.First(&u, id)

	return u
}

func (dao *BaseDao[T]) UpdateById(entityData T) int64 {
	tx := dao.db.Model(&dao.model).Updates(entityData)
	return tx.RowsAffected
}

func (dao *BaseDao[T]) DeleteById(id int64) int64 {
	u := CreateEntityAndSetId(dao.model, id)
	/// 删除一条已有的记录（email 的主键值为 10）
	tx := dao.db.Delete(&u)
	// DELETE from emails where id=10;

	return tx.RowsAffected
}

func (dao *BaseDao[T]) GetDb() *gorm.DB {
	return dao.db
}

// BeginTx 开启事务：开启事务之后，必须使用开启事务返回的*gorm.DB, 而不是开启事务时使用*gorm.DB
func (dao *BaseDao[T]) BeginTx(opts ...*sql.TxOptions) {
	dao.db.Begin()

}

// RollbackTx 事务回滚
func (dao *BaseDao[T]) RollbackTx() {
	dao.db.Rollback()
}

// CommitTx 事务提交
func (dao *BaseDao[T]) CommitTx() {
	dao.db.Commit()
}
